#!/usr/bin/env python
#
# Routines for reading VO records written by the vo_format_writer input module
#
# Author:   Mike Murphy <mamurph@cs.clemson.edu>
# Revision: 23 September 2009
#
#   Copyright 2009 Clemson University
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# This material is based upon work supported under a National Science
# Foundation Graduate Research Fellowship. Any opinions, findings,
# conclusions or recommendations expressed in this publication are those of
# the author(s) and do not necessarily reflect the views of the National
# Science Foundation.

'''
Mechanism for reading VO format files produced by the vo_format_writer input
module.
'''

from common_reader import CommonReader
from results import VOResult

VO_FORMAT = 0.90


class VO(dict):
   '''
   Representation of a single Virtual Organization, along with any data about
   the VO (such as target and limit levels for corresponding VOCs) contained
   in the VO input file. Each property of the VO is named with a string and
   stored in a dictionary-like fashion
   '''
   def __init__(self, name):
      '''
      @param name: Name of the VO
      @type name: str
      '''
      dict.__init__(self)
      self.name = name
#


class VOCollection(dict):
   '''
   Collection of VO objects for use with the simulator. This class subclasses
   the built-in dictionary type.
   '''
   pass
#


class VOReader(CommonReader):
   '''
   Mechanism for reading Virtual Organization list files, which specify the
   VOs presently valid on the grid, along with the target and limit levels
   for VOCs dedicated to those VOs.
   '''
   def __init__(self, filename, fh, simobj, vo_map):
      '''
      @param filename: Name of open VO list file
      @type filename: str
      @param fh: Handle to open VO list file (r mode)
      @param simobj: Reference to the simulator instance
      @param vo_map: Dictionary-like object into which VO classes will be
                     inserted (form vo_name: vo_instance)
      '''
      prefix = 'vometa_' + filename + '_'
      CommonReader.__init__(self, filename, fh, simobj, VO_FORMAT, prefix)
      self.add_handler('$', self.h_vo)
      self.vo_map = vo_map
   def h_vo(self):
      '''
      Parse handler for VO description entries

      @rtype: bool
      @return: True
      '''
      if not self.in_clock_block:
         self.error('VO entries are valid only in clock blocks')
      if len(self.parts) < 2:
         self.error('VO entries require at least 1 argument')
      try:
         vo = self.parts[1]
         rec = VO(vo)
         for part in self.parts[2:]:
            key, value = part.split(':')
            rec[key] = typeconvert(value)
         self.vo_map[vo] = rec
         r = VOResult(self.sim.get_timestamp(), vo, rec)
         self.sim.add_result(r)
      except Exception, msg:
         self.error(msg)
      return True
#


def typeconvert(s):
   '''
   Converts a string into a float, int, or bool, if possible.

   @param s: String to convert
   @type s: str

   @return: the converted value, or the raw string if conversion was not
   possible
   '''
   cval = None
   try:
      cval = float(s)
      ci = int(cval)
      if ci == cval:
         cval = ci
   except Exception:
      if s.lower() == 'true':
         cval = True
      elif s.lower() == 'false':
         cval = False
      else:
         cval = s
   return cval
#
